home *** CD-ROM | disk | FTP | other *** search
- #include <BSpline.h>
- #include <ElmItgRules.h>
- #include <math.h>
-
- // This demo program is meant to demonstrate some features of
- // the spline package and class 'ElmItgRules' in DIFFPACK.
-
- // Two functions (sin(x) & cos(x) for ex.) are interpolated by splines
- // 'spline1' & 'spline2', then \int_a^b (spline1*spline2) is calculated.
- // Numerical integration is used in the calculation.
- // The optimization due to the unform knot vector is not implemented.
-
- // ======================== optimal version ==========================
-
- // specific constants for the particular case of the f_1 and f_2 functions:
- const real a = 0.0; // integration region
- const real b = M_PI/2.0;
- int k = 4; // cubic splines as default
- int nitg_order = 4; // order of numerical integration
-
- real f_1 (real x) { return sin(x); } // two analytical functions
- real f_2 (real x) { return cos(x); }
-
- int main (int nargs, const char** args)
- {
- if (nargs<2)
- errorFP("main:","Usage: %s num_knots (nitg_order k)",args[0]);
-
- if (nargs>2) nitg_order = atoi(args[2]);
- if (nargs>3) k = atoi(args[3]);
-
- KnotVec knots (atoi(args[1])); // number of unique knots from input
- knots.fill (a,b); // uniform knot vector (not necessary)
- knots.regulate (k); // make a k-regular knot vector
-
- SplineSpace space (knots,k); // the corresponding spline space
-
- int n = space.dimension(); // total number of B-spline basis functions
- int derivative_order_i=0; // derivative order for B_i(x)
- int derivative_order_j=0; // derivative order for B_j(x)
- Mat(real) BS(1,k); // assistant variables
- int miu1,miu2,l,r,i,j,m,s;
- real x; // a point in [a,b]
- real scale; // scaling for x -> [-1,1] num.itg. interval
-
- BSpline spline1, spline2; // two spline functions
- spline1.redim (space);
- spline2.redim (space);
-
- // let spline1 interpolate the f_1 function and spline2 interpolate f_2:
- Vec(real) xs(n); // x coordinates in [a,b]
- Vec(real) fs(n); // f_1 and f_2 values over xs
- Vec(real) coef1(n), coef2(n); // spline coeff. for spline1 and spline2
- xs.fill (a,b);
- fs = xs; fs.apply (f_1); // fs contains f_1 values
- spline1.interpolation (xs,fs); // spline interpolation of function f_1
- spline1.getCoef (coef1); // coefficients for spline1
- fs = xs; fs.apply (f_2); // fs contains f_2 values
- spline2.interpolation (xs,fs); // spline interpolation of function f_2
- spline2.getCoef (coef2); // coefficients for spline2
-
- ElmItgRules rule (GAUSS_POINTS); // used for numerical integration
- rule.refill (nitg_order, 1 /*1D*/, BOX /*domain: box (or interval)*/);
- Ptv(real) pt(1); // used to hold a numerical integration point
-
- // B-spline values at all the numerical integration points:
- ArrayGenSimple(real) bs1(n,nitg_order,k), bs2(n,nitg_order,k);
- bs1.fill(0.0); bs2.fill(0.0);
-
- // first calculate all B-spline values, bs1 and bs2:
- for (m=1; m<=n; m++)
- if (knots(m)<knots(m+1)) // nonempty interval
- {
- miu1 = miu2 = m;
- scale = (knots(m+1)-knots(m))/2.0;
-
- for (s=1; s<=nitg_order; s++)
- {
- rule.point (pt,s);
- x = knots(m) + (pt(1)+1.0)*scale;
-
- space.BSplines (x,derivative_order_i,BS,miu1,dpTRUE);
-
- for (i=1; i<=k; i++) bs1(m,s,i) = BS(1,i);
-
- if (derivative_order_j != derivative_order_i)
- space.BSplines (x,derivative_order_j,BS,miu2,dpTRUE);
-
- for (i=1; i<=k; i++) bs2(m,s,i) = BS(1,i);
- }
- }
- real I = 0.0; // for containing integration result
-
- for (i=1; i<=n; i++) // integrate numerically
- for (j=1; j<=((derivative_order_i == derivative_order_j) ? i:n); j++)
- if ( abs(i-j) < k ) // B_i(x)*B_j(x) is different from 0
- {
- l = max(i,j); // actual integration region
- r = min(i,j)+k;
-
- for (m=l; m<r; m++)
- if (knots(m+1)>knots(m))
- {
- scale = (knots(m+1)-knots(m))/2.0;
- miu1 = miu2 = m;
-
- for (s=1; s<=nitg_order; s++)
- {
- if (derivative_order_i==derivative_order_j && j < i)
- I += (coef1(i)*coef2(j)+coef1(j)*coef2(i))
- *bs1(m,s,i-miu1+k)*bs2(m,s,j-miu2+k)
- *rule.weight(s)*scale;
- else
- I += coef1(i)*coef2(j)
- *bs1(m,s,i-miu1+k)*bs2(m,s,j-miu2+k)
- *rule.weight(s)*scale;
- }
- }
- }
-
- s_o<<oform("Integration result with spline k=%d and nitg_order=%d is %g\n",
- k,nitg_order,I);
- return 0;
- }
-